package auths

import (
	"context"
	"errors"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/loggers"
	"github.com/dgrijalva/jwt-go"
	"go.uber.org/zap"
)

var (
	ERROR_NOT_AUTH = errors.New("not auth")
)

type RbacClaim struct {
	jwt.StandardClaims
	UserInfo
}

func ParseRbac(publicKey []byte, tokenValue string) (*RbacClaim, error) {
	token, err := jwt.ParseWithClaims(tokenValue, &RbacClaim{}, func(token *jwt.Token) (interface{}, error) {
		return jwt.ParseRSAPublicKeyFromPEM(publicKey)
	})
	if err != nil {
		return nil, err
	}
	if token == nil || !token.Valid {
		return nil, errors.New("解析jwt失败")
	}
	if claims, ok := token.Claims.(*RbacClaim); ok {
		return claims, nil
	} else {
		return nil, errors.New("解析jwt失败")
	}

}

func NewCtxWithRbacAuth(publicKey, tokenValue string, ctx context.Context) (context.Context, error) {
	rbacClaim, err := ParseRbac([]byte(publicKey), tokenValue)
	if err != nil {
		loggers.Error("解析rbac失败", ctx, zap.Error(err), zap.String("publicKey", publicKey), zap.String("token", tokenValue))
		return ctx, ERROR_NOT_AUTH
	}
	userInfo := rbacClaim.UserInfo
	newCtx := context.WithValue(ctx, USER_INFO_KEY, &userInfo)
	newCtx = context.WithValue(newCtx, TOKEN_KEY, &tokenValue)
	return newCtx, nil
}
